package com.i2863.shiroDemo.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.i2863.shiroDemo.annotation.SysLog;
import com.i2863.shiroDemo.dto.ResultInfo;
import com.i2863.shiroDemo.dto.UserDto;
import com.i2863.shiroDemo.dto.UserInfo;
import com.i2863.shiroDemo.util.StringUtils;
import com.i2863.shiroDemo.entity.Role;
import com.i2863.shiroDemo.entity.User;
import com.i2863.shiroDemo.service.IRoleService;
import com.i2863.shiroDemo.service.IUserService;
import com.i2863.shiroDemo.util.PasswordEncoder;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("user")
public class UserController extends BaseController {

    @Resource
    private IUserService iUserService;
    @Resource
    private IRoleService iRoleService;

    @RequestMapping("list")
    public String list(Model model) {
        List<Role> list = iRoleService.list();
        list.remove(this.getSuperRole());
        model.addAttribute("roleList", list);
        return "user/user_list";
    }

    @RequestMapping("info")
    public String userInfo() {
        return "user/user_info";
    }

    @RequestMapping("center")
    public String userCenter() {
        return "user/admin_center";
    }

    @RequestMapping("change")
    public String userChange() {
        return "user/admin_change";
    }

    @RequestMapping("unlock")
    @ResponseBody
    public ResultInfo<Boolean> unlock(@RequestParam("password") String password) {
        UserInfo userInfo = this.getUserInfo();
        SimpleHash simpleHash = new SimpleHash("md5", password, userInfo.getCredentialsSalt(), 2);
        if (simpleHash.toString().equals(userInfo.getPassWord())) {
            return new ResultInfo<>(true);
        }
        return new ResultInfo<>(false);
    }

    @RequestMapping("listData")
    @RequiresPermissions("user:view")
    @ResponseBody
    @SuppressWarnings("unchecked")
    public ResultInfo<List<UserDto>> listData(User user, Integer page, Integer limit) {
        QueryWrapper<User> wrapper = new QueryWrapper<>(user);
        if (user != null && user.getUserName() != null) {
            wrapper.like("user_name", user.getUserName());
            user.setUserName(null);
        }
        if (user != null && user.getName() != null) {
            wrapper.like("name", user.getName());
            user.setName(null);
        }
        IPage<User> pageObj = iUserService.page(new Page<>(page, limit), wrapper);
        List<User> users = (List<User>) this.getSession().getAttribute("superUsers");
        pageObj.getRecords().removeAll(users);

        List<Role> list = iRoleService.list();
        list.remove(this.getSuperRole());
        Map<Integer, String> map = list.stream().collect(Collectors.toMap(Role::getId, Role::getRoleName));

        List<UserDto> userDtoList = pageObj.getRecords().stream().map(u -> {
            UserDto userDto = new UserDto(u);
            userDto.setRoleName(map.get(userDto.getRoleId()));
            return userDto;
        }).collect(Collectors.toList());

        return new ResultInfo<>(userDtoList, pageObj.getTotal());
    }

    @SysLog("添加用户操作")
    @ResponseBody
    @RequestMapping("add")
    @RequiresPermissions("user:add")
    public ResultInfo<Boolean> add(User user) {
        Map<String, String> map = PasswordEncoder.enCodePassWord(user.getUserName(), user.getPassWord());
        User user1 = iUserService.getOne(new QueryWrapper<User>().eq("user_name", user.getUserName()));
        if (user1 != null) {
            return new ResultInfo<>(500, "用户登录名重复！");
        }
        user.setSalt(map.get(PasswordEncoder.SALT));
        user.setPassWord(map.get(PasswordEncoder.PASSWORD));
        boolean b = iUserService.save(user);
        return new ResultInfo<>(b);
    }

    @SysLog("删除用户操作")
    @ResponseBody
    @RequestMapping("delBatch")
    @RequiresPermissions("user:del")
    public ResultInfo<Boolean> delBatch(Integer[] idArr) {
        boolean b = iUserService.removeByIds(Arrays.asList(idArr));
        return new ResultInfo<>(b);
    }

    @SysLog("修改用户操作")
    @ResponseBody
    @RequestMapping("edit")
    @RequiresPermissions("user:edit")
    public ResultInfo<Boolean> edit(User user) {
        User us = iUserService.getById(user.getId());
        us.setName(user.getName());
        us.setRoleId(user.getRoleId());
        us.setState(user.getState());
        boolean b = iUserService.updateById(us);
        return new ResultInfo<>(b);
    }

    @SysLog("修改用户")
    @ResponseBody
    @RequestMapping("userEdit")
    public ResultInfo<Boolean> userEdit(User user) {
        UserInfo userInfo = this.getUserInfo();
        User us = iUserService.getById(userInfo.getId());
        if (!StringUtils.isEmpty(user.getName())) {
            us.setName(user.getName());
        }
        if (!StringUtils.isEmpty(user.getPassWord())) {
            Map<String, String> map = PasswordEncoder.enCodePassWord(us.getUserName(), user.getPassWord());
            us.setSalt(map.get(PasswordEncoder.SALT));
            us.setPassWord(map.get(PasswordEncoder.PASSWORD));
        }
        boolean b = iUserService.updateById(us);
        return new ResultInfo<>(b);
    }

    @ResponseBody
    @RequestMapping("centerDate")
    public ResultInfo<UserInfo> centerDate() {
        UserInfo userInfo = this.getUserInfo();
        BeanUtils.copyProperties(iUserService.getById(userInfo.getId()), userInfo);
        return new ResultInfo<>(userInfo);
    }

    @ResponseBody
    @RequestMapping("count")
    @SuppressWarnings("unchecked")
    public ResultInfo<Integer> count() {
        List<User> allUser = iUserService.list();
        List<User> superUser = (List<User>) this.getSession().getAttribute("superUsers");
        allUser.removeAll(superUser);
        return new ResultInfo<>(allUser.size());
    }

    @SysLog("重置密码")
    @ResponseBody
    @RequestMapping("rePwdBatch")
    @RequiresPermissions("*")
    public ResultInfo<Boolean> rePwdBatch(Integer[] idArr) {
        if (idArr != null && idArr.length > 0) {
            List<User> users = new ArrayList<>();
            for (Integer id : idArr) {
                User user = iUserService.getById(id);
                if (user != null) {
                    Map<String, String> map = PasswordEncoder.enCodePassWord(user.getUserName(), "123456");
                    user.setSalt(map.get(PasswordEncoder.SALT));
                    user.setPassWord(map.get(PasswordEncoder.PASSWORD));
                    user.setUpdateTime(new Date());
                    users.add(user);
                }

            }
            if (users.size() > 0) {
                iUserService.updateBatchById(users);
            }
        }
        return new ResultInfo<>(true);
    }
}